home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / fsp / part02 < prev    next >
Encoding:
Internet Message Format  |  1991-12-13  |  60.7 KB

  1. Subject: v25i025: A real-time, multithreaded Internet archive server, Part02/03
  2. Newsgroups: comp.sources.unix
  3. Approved: vixie@pa.dec.com
  4.  
  5. Submitted-By: wen-king@vlsi.cs.caltech.edu
  6. Posting-Number: Volume 25, Issue 25
  7. Archive-Name: fsp/part02
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line, then unpack
  11. # it by saving it into a file and typing "sh file".  To overwrite existing
  12. # files, type "sh file -c".  You can also feed this as standard input via
  13. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  14. # will see the following message at the end:
  15. #        "End of archive 2 (of 3)."
  16. # Contents:  Makefile bsd_src/glob.c bsd_src/print.c client_util.c
  17. #   common_def.h server_host.c server_lib.c server_main.c udp_io.c
  18. # Wrapped by vixie@cognition.pa.dec.com on Fri Dec 13 17:53:11 1991
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'Makefile'\"
  22. else
  23. echo shar: Extracting \"'Makefile'\" \(6894 characters\)
  24. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  25. X#############################################################################
  26. X# You need to do a successful 'make' in the bsd_src directory first before
  27. X# trying to run 'make' in this directory.  The bsd_src directory contains
  28. X# several files derived from those found in the uunet.uu.net archive.
  29. X# Run "make install" to install binaries.
  30. X# Run "make installm" to install man pages.
  31. X# Run "make de-install" to remove installed binaries and man pages.
  32. X
  33. X#############################################################################
  34. X# This is where you want to install the binary
  35. X#
  36. BIN=/usr/local/bin
  37. X
  38. X#############################################################################
  39. X# This is where you want to install the man pages
  40. X#
  41. MAN=/usr/local/man/man1
  42. X
  43. X#############################################################################
  44. X# If you want to provide FSP service, this should be set to the working
  45. X# directory of the FSP server.
  46. X#
  47. DEF_FSP_HOME=/usr/tmp
  48. X
  49. X#############################################################################
  50. X# If you want to provide FSP service, this should be set to the UDP socket
  51. X# port number the FSP server should use.
  52. X#
  53. DEF_FSP_PORT=21
  54. X
  55. X#############################################################################
  56. X# This is where the version number string comes from:
  57. X#
  58. VERSION_STR="Original Caltech version 1.0, Dec 1991"
  59. X
  60. X#############################################################################
  61. X# FSP uses BSD random/srandom functions.  If your system does not have
  62. X# them, include them from the bsd_src directory.
  63. X#
  64. X#RANDOM=bsd_src/random.o
  65. X
  66. X#############################################################################
  67. CFLAGS=-g
  68. X
  69. PROGS=    fspd flscmd fcdcmd fgetcmd frmcmd frmdircmd fprocmd \
  70. X    fmkdir fput fver fcatcmd
  71. X
  72. IPROGS=    ${BIN}/fspd ${BIN}/flscmd ${BIN}/fcdcmd \
  73. X    ${BIN}/fgetcmd ${BIN}/frmcmd ${BIN}/frmdircmd ${BIN}/fprocmd \
  74. X    ${BIN}/fmkdir ${BIN}/fput ${BIN}/fver ${BIN}/fcatcmd
  75. X
  76. IMANS=    ${MAN}/fcatcmd.1 ${MAN}/fcat.1 ${MAN}/fcdcmd.1 ${MAN}/fcd.1 \
  77. X    ${MAN}/fgetcmd.1 ${MAN}/fget.1 ${MAN}/flscmd.1 ${MAN}/fls.1 \
  78. X    ${MAN}/fmkdir.1 ${MAN}/fprocmd.1 ${MAN}/fpro.1 ${MAN}/fput.1 \
  79. X    ${MAN}/frmcmd.1 ${MAN}/frm.1 ${MAN}/frmdircmd.1 ${MAN}/frmdir.1 \
  80. X    ${MAN}/fspd.1 ${MAN}/fver.1
  81. X
  82. all:
  83. X    @ cd bsd_src; make
  84. X    @ make all1
  85. X
  86. all1:      ${PROGS}
  87. install:  ${IPROGS}
  88. installm: ${IMANS}
  89. X
  90. SERVER_OBJ= server_main.o server_lib.o server_host.o udp_io.o server_file.o
  91. CLIENT_OBJ= client_lib.o udp_io.o client_util.o
  92. GLOB_OBJ= bsd_src/glob.o
  93. UTIL_LS_OBJ= bsd_src/cmp.o bsd_src/ls.o bsd_src/print.o bsd_src/util.o \
  94. X        ${GLOB_OBJ}
  95. X
  96. X#############################################################################
  97. X
  98. fspd: ${SERVER_OBJ} ${RANDOM}
  99. X    cc ${CFLAGS} -o fspd ${SERVER_OBJ} ${RANDOM} ${LIB}
  100. X
  101. fgetcmd: fgetcmd.o ${CLIENT_OBJ} ${GLOB_OBJ}
  102. X    cc ${CFLAGS} -o fgetcmd fgetcmd.o ${CLIENT_OBJ} ${GLOB_OBJ} ${LIB}
  103. X
  104. fcatcmd: fcatcmd.o ${CLIENT_OBJ} ${GLOB_OBJ}
  105. X    cc ${CFLAGS} -o fcatcmd fcatcmd.o ${CLIENT_OBJ} ${GLOB_OBJ} ${LIB}
  106. X
  107. fput: fput.o ${CLIENT_OBJ}
  108. X    cc ${CFLAGS} -o fput fput.o ${CLIENT_OBJ} ${LIB}
  109. X
  110. frmcmd: frmcmd.o ${CLIENT_OBJ} ${GLOB_OBJ}
  111. X    cc ${CFLAGS} -o frmcmd frmcmd.o ${CLIENT_OBJ} ${GLOB_OBJ} ${LIB}
  112. X
  113. flscmd: flscmd.o ${CLIENT_OBJ} ${UTIL_LS_OBJ}
  114. X    cc ${CFLAGS} -o flscmd flscmd.o ${CLIENT_OBJ} ${UTIL_LS_OBJ} ${LIB}
  115. X
  116. fcdcmd: fcdcmd.o ${CLIENT_OBJ} ${GLOB_OBJ}
  117. X    cc ${CFLAGS} -o fcdcmd fcdcmd.o ${CLIENT_OBJ} ${GLOB_OBJ} ${LIB}
  118. X
  119. frmdircmd: frmdircmd.o ${CLIENT_OBJ} ${GLOB_OBJ}
  120. X    cc ${CFLAGS} -o frmdircmd frmdircmd.o ${CLIENT_OBJ} ${GLOB_OBJ} ${LIB}
  121. X
  122. fprocmd: fprocmd.o ${CLIENT_OBJ} ${GLOB_OBJ}
  123. X    cc ${CFLAGS} -o fprocmd fprocmd.o ${CLIENT_OBJ} ${GLOB_OBJ} ${LIB}
  124. X
  125. fmkdir: fmkdir.o ${CLIENT_OBJ}
  126. X    cc ${CFLAGS} -o fmkdir fmkdir.o ${CLIENT_OBJ} ${LIB}
  127. X
  128. fver: fver.o ${CLIENT_OBJ}
  129. X    cc ${CFLAGS} -o fver fver.o ${CLIENT_OBJ} ${LIB}
  130. X
  131. X#############################################################################
  132. X
  133. X${BIN}/fspd     : fspd      ; cp fspd      ${BIN}/fspd
  134. X${BIN}/fgetcmd  : fgetcmd   ; cp fgetcmd   ${BIN}/fgetcmd
  135. X${BIN}/fcatcmd  : fcatcmd   ; cp fcatcmd   ${BIN}/fcatcmd
  136. X${BIN}/fput     : fput      ; cp fput      ${BIN}/fput
  137. X${BIN}/frmcmd   : frmcmd    ; cp frmcmd    ${BIN}/frmcmd
  138. X${BIN}/flscmd   : flscmd    ; cp flscmd    ${BIN}/flscmd
  139. X${BIN}/fcdcmd   : fcdcmd    ; cp fcdcmd    ${BIN}/fcdcmd
  140. X${BIN}/frmdircmd: frmdircmd ; cp frmdircmd ${BIN}/frmdircmd
  141. X${BIN}/fprocmd  : fprocmd   ; cp fprocmd   ${BIN}/fprocmd
  142. X${BIN}/fmkdir   : fmkdir    ; cp fmkdir    ${BIN}/fmkdir
  143. X${BIN}/fver     : fver      ; cp fver      ${BIN}/fver
  144. X
  145. X#############################################################################
  146. X
  147. X${MAN}/fcat.1     : fcatcmd.1  ; cp fcatcmd.1   ${MAN}/fcat.1
  148. X${MAN}/fcatcmd.1  : fcatcmd.1  ; cp fcatcmd.1   ${MAN}/fcatcmd.1
  149. X${MAN}/fcd.1      : fcdcmd.1   ; cp fcdcmd.1    ${MAN}/fcd.1
  150. X${MAN}/fcdcmd.1   : fcdcmd.1   ; cp fcdcmd.1    ${MAN}/fcdcmd.1
  151. X${MAN}/fget.1     : fgetcmd.1  ; cp fgetcmd.1   ${MAN}/fget.1
  152. X${MAN}/fgetcmd.1  : fgetcmd.1  ; cp fgetcmd.1   ${MAN}/fgetcmd.1
  153. X${MAN}/fls.1      : flscmd.1   ; cp flscmd.1    ${MAN}/fls.1
  154. X${MAN}/flscmd.1   : flscmd.1   ; cp flscmd.1    ${MAN}/flscmd.1
  155. X${MAN}/fmkdir.1   : fmkdir.1   ; cp fmkdir.1    ${MAN}/fmkdir.1
  156. X${MAN}/fpro.1     : fprocmd.1  ; cp fprocmd.1   ${MAN}/fpro.1
  157. X${MAN}/fprocmd.1  : fprocmd.1  ; cp fprocmd.1   ${MAN}/fprocmd.1
  158. X${MAN}/fput.1     : fput.1     ; cp fput.1      ${MAN}/fput.1
  159. X${MAN}/frm.1      : frmcmd.1   ; cp frmcmd.1    ${MAN}/frm.1
  160. X${MAN}/frmcmd.1   : frmcmd.1   ; cp frmcmd.1    ${MAN}/frmcmd.1
  161. X${MAN}/frmdir.1   : frmdircmd.1; cp frmdircmd.1 ${MAN}/frmdir.1
  162. X${MAN}/frmdircmd.1: frmdircmd.1; cp frmdircmd.1 ${MAN}/frmdircmd.1
  163. X${MAN}/fspd.1     : fspd.1     ; cp fspd.1      ${MAN}/fspd.1
  164. X${MAN}/fver.1     : fver.1     ; cp fver.1      ${MAN}/fver.1
  165. X
  166. X#############################################################################
  167. X
  168. server_main.o: server_main.c server_def.h common_def.h Makefile
  169. X    cc ${CFLAGS} -DDEF_FSP_PORT=${DEF_FSP_PORT}    \
  170. X             -DDEF_FSP_HOME=\"${DEF_FSP_HOME}\"    \
  171. X             -DVERSION_STR=\"${VERSION_STR}\"    \
  172. X             -c server_main.c
  173. X
  174. client_lib.o: client_lib.c client_def.h common_def.h
  175. client_util.o: client_util.c client_def.h common_def.h
  176. fcatcmd.o: fcatcmd.c client_def.h common_def.h
  177. fcdcmd.o: fcdcmd.c client_def.h common_def.h
  178. fgetcmd.o: fgetcmd.c client_def.h common_def.h
  179. flscmd.o: flscmd.c client_def.h common_def.h
  180. fmkdir.o: fmkdir.c client_def.h common_def.h
  181. fprocmd.o: fprocmd.c client_def.h common_def.h
  182. fput.o: fput.c client_def.h common_def.h
  183. frmcmd.o: frmcmd.c client_def.h common_def.h
  184. fver.o: fver.c client_def.h common_def.h
  185. frmdircmd.o: frmdircmd.c client_def.h common_def.h
  186. server_host.o: server_host.c server_def.h common_def.h
  187. server_file.o: server_file.c server_def.h common_def.h
  188. server_lib.o: server_lib.c server_def.h common_def.h
  189. server_main.o: server_main.c server_def.h common_def.h
  190. udp_io.o: udp_io.c common_def.h
  191. X
  192. clean:
  193. X    rm -f *.o ${PROGS}
  194. X    @ cd bsd_src; make clean
  195. X
  196. de-install:
  197. X    rm -f ${IPROGS} ${IMANS}
  198. END_OF_FILE
  199. if test 6894 -ne `wc -c <'Makefile'`; then
  200.     echo shar: \"'Makefile'\" unpacked with wrong size!
  201. fi
  202. # end of 'Makefile'
  203. fi
  204. if test -f 'bsd_src/glob.c' -a "${1}" != "-c" ; then 
  205.   echo shar: Will not clobber existing file \"'bsd_src/glob.c'\"
  206. else
  207. echo shar: Extracting \"'bsd_src/glob.c'\" \(10080 characters\)
  208. sed "s/^X//" >'bsd_src/glob.c' <<'END_OF_FILE'
  209. X/*
  210. X * Copyright (c) 1980 Regents of the University of California.
  211. X * All rights reserved.
  212. X *
  213. X * Redistribution and use in source and binary forms are permitted
  214. X * provided that the above copyright notice and this paragraph are
  215. X * duplicated in all such forms and that any documentation,
  216. X * advertising materials, and other materials related to such
  217. X * distribution and use acknowledge that the software was developed
  218. X * by the University of California, Berkeley.  The name of the
  219. X * University may not be used to endorse or promote products derived
  220. X * from this software without specific prior written permission.
  221. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  222. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  223. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  224. X */
  225. X
  226. X#ifndef lint
  227. static char sccsid[] = "@(#)glob.c    5.4 (Berkeley) 6/29/88";
  228. X#endif /* not lint */
  229. X
  230. X/*
  231. X * C-shell glob for random programs.
  232. X */
  233. X
  234. X#include "../client_def.h"
  235. X#include "tweak.h"
  236. X
  237. X#define    QUOTE 0200
  238. X#define    TRIM 0177
  239. X#define    eq(a,b)        (strcmp(a, b)==0)
  240. X#define    GAVSIZ        (NCARGS/6)
  241. X#define    isdir(d)    ((d.st_mode & S_IFMT) == S_IFDIR)
  242. X
  243. static    char **gargv;        /* Pointer to the (stack) arglist */
  244. static    int gargc;        /* Number args in gargv */
  245. static    int gnleft;
  246. static    int gflag;
  247. static    int tglob();
  248. char    **glob();
  249. char    *globerr;
  250. char    *home;
  251. struct    passwd *getpwnam();
  252. extern    int errno;
  253. static    char *strspl(), *strend();
  254. char    *malloc(), *strcpy(), *strcat();
  255. char    **copyblk();
  256. X
  257. static    int globcnt;
  258. X
  259. char    *globchars = "`{[*?";
  260. X
  261. static    char *gpath, *gpathp, *lastgpathp;
  262. static    int globbed;
  263. static    char *entp;
  264. static    char **sortbas;
  265. X
  266. char **
  267. glob(v)
  268. X    register char *v;
  269. X{
  270. X    char agpath[BUFSIZ];
  271. X    char *agargv[GAVSIZ];
  272. X    char *vv[2];
  273. X    vv[0] = v;
  274. X    vv[1] = 0;
  275. X    gflag = 0;
  276. X    rscan(vv, tglob);
  277. X    if (gflag == 0)
  278. X        return (copyblk(vv));
  279. X
  280. X    globerr = 0;
  281. X    gpath = agpath; gpathp = gpath; *gpathp = 0;
  282. X    lastgpathp = &gpath[sizeof agpath - 2];
  283. X    ginit(agargv); globcnt = 0;
  284. X    collect(v);
  285. X    if (globcnt == 0 && (gflag&1)) {
  286. X        blkfree(gargv), gargv = 0;
  287. X        return (0);
  288. X    } else
  289. X        return (gargv = copyblk(gargv));
  290. X}
  291. X
  292. static
  293. ginit(agargv)
  294. X    char **agargv;
  295. X{
  296. X
  297. X    agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
  298. X    gnleft = NCARGS - 4;
  299. X}
  300. X
  301. static
  302. collect(as)
  303. X    register char *as;
  304. X{
  305. X    if (eq(as, "{") || eq(as, "{}")) {
  306. X        Gcat(as, "");
  307. X        sort();
  308. X    } else
  309. X        acollect(as);
  310. X}
  311. X
  312. static
  313. acollect(as)
  314. X    register char *as;
  315. X{
  316. X    register int ogargc = gargc;
  317. X
  318. X    gpathp = gpath; *gpathp = 0; globbed = 0;
  319. X    expand(as);
  320. X    if (gargc != ogargc)
  321. X        sort();
  322. X}
  323. X
  324. static
  325. sort()
  326. X{
  327. X    register char **p1, **p2, *c;
  328. X    char **Gvp = &gargv[gargc];
  329. X
  330. X    p1 = sortbas;
  331. X    while (p1 < Gvp-1) {
  332. X        p2 = p1;
  333. X        while (++p2 < Gvp)
  334. X            if (strcmp(*p1, *p2) > 0)
  335. X                c = *p1, *p1 = *p2, *p2 = c;
  336. X        p1++;
  337. X    }
  338. X    sortbas = Gvp;
  339. X}
  340. X
  341. static
  342. expand(as)
  343. X    char *as;
  344. X{
  345. X    register char *cs;
  346. X    register char *sgpathp, *oldcs;
  347. X    struct stat stb;
  348. X
  349. X    sgpathp = gpathp;
  350. X    cs = as;
  351. X    if (*cs == '~' && gpathp == gpath) {
  352. X        addpath('~');
  353. X        for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
  354. X            addpath(*cs++);
  355. X        if (!*cs || *cs == '/') {
  356. X            if (gpathp != gpath + 1) {
  357. X                *gpathp = 0;
  358. X                if (gethdir(gpath + 1))
  359. X                    globerr = "Unknown user name after ~";
  360. X                (void) strcpy(gpath, gpath + 1);
  361. X            } else
  362. X                (void) strcpy(gpath, home);
  363. X            gpathp = strend(gpath);
  364. X        }
  365. X    }
  366. X    while (!any(*cs, globchars)) {
  367. X        if (*cs == 0) {
  368. X            if (!globbed)
  369. X                Gcat(gpath, "");
  370. X            else if (util_stat(gpath, &stb) >= 0) {
  371. X                Gcat(gpath, "");
  372. X                globcnt++;
  373. X            }
  374. X            goto endit;
  375. X        }
  376. X        addpath(*cs++);
  377. X    }
  378. X    oldcs = cs;
  379. X    while (cs > as && *cs != '/')
  380. X        cs--, gpathp--;
  381. X    if (*cs == '/')
  382. X        cs++, gpathp++;
  383. X    *gpathp = 0;
  384. X    if (*oldcs == '{') {
  385. X        (void) execbrc(cs, ((char *)0));
  386. X        return;
  387. X    }
  388. X    matchdir(cs);
  389. endit:
  390. X    gpathp = sgpathp;
  391. X    *gpathp = 0;
  392. X}
  393. X
  394. static
  395. matchdir(pattern)
  396. X    char *pattern;
  397. X{
  398. X    struct stat stb;
  399. X    register struct rdirent *dp;
  400. X    RDIR *dirp;
  401. X
  402. X    dirp = util_opendir(gpath);
  403. X    if (dirp == NULL) {
  404. X        if (globbed)
  405. X            return;
  406. X        goto patherr2;
  407. X    }
  408. X    if (util_stat(gpath, &stb) < 0)
  409. X        goto patherr1;
  410. X    if (!isdir(stb)) {
  411. X        errno = ENOTDIR;
  412. X        goto patherr1;
  413. X    }
  414. X    while ((dp = util_readdir(dirp)) != NULL) {
  415. X        if (dp->d_ino == 0)
  416. X            continue;
  417. X        if (match(dp->d_name, pattern)) {
  418. X            Gcat(gpath, dp->d_name);
  419. X            globcnt++;
  420. X        }
  421. X    }
  422. X    util_closedir(dirp);
  423. X    return;
  424. X
  425. patherr1:
  426. X    util_closedir(dirp);
  427. patherr2:
  428. X    globerr = "Bad directory components";
  429. X}
  430. X
  431. static
  432. execbrc(p, s)
  433. X    char *p, *s;
  434. X{
  435. X    char restbuf[BUFSIZ + 2];
  436. X    register char *pe, *pm, *pl;
  437. X    int brclev = 0;
  438. X    char *lm, savec, *sgpathp;
  439. X
  440. X    for (lm = restbuf; *p != '{'; *lm++ = *p++)
  441. X        continue;
  442. X    for (pe = ++p; *pe; pe++)
  443. X    switch (*pe) {
  444. X
  445. X    case '{':
  446. X        brclev++;
  447. X        continue;
  448. X
  449. X    case '}':
  450. X        if (brclev == 0)
  451. X            goto pend;
  452. X        brclev--;
  453. X        continue;
  454. X
  455. X    case '[':
  456. X        for (pe++; *pe && *pe != ']'; pe++)
  457. X            continue;
  458. X        continue;
  459. X    }
  460. pend:
  461. X    brclev = 0;
  462. X    for (pl = pm = p; pm <= pe; pm++)
  463. X    switch (*pm & (QUOTE|TRIM)) {
  464. X
  465. X    case '{':
  466. X        brclev++;
  467. X        continue;
  468. X
  469. X    case '}':
  470. X        if (brclev) {
  471. X            brclev--;
  472. X            continue;
  473. X        }
  474. X        goto doit;
  475. X
  476. X    case ','|QUOTE:
  477. X    case ',':
  478. X        if (brclev)
  479. X            continue;
  480. doit:
  481. X        savec = *pm;
  482. X        *pm = 0;
  483. X        (void) strcpy(lm, pl);
  484. X        (void) strcat(restbuf, pe + 1);
  485. X        *pm = savec;
  486. X        if (s == 0) {
  487. X            sgpathp = gpathp;
  488. X            expand(restbuf);
  489. X            gpathp = sgpathp;
  490. X            *gpathp = 0;
  491. X        } else if (amatch(s, restbuf))
  492. X            return (1);
  493. X        sort();
  494. X        pl = pm + 1;
  495. X        if (brclev)
  496. X            return (0);
  497. X        continue;
  498. X
  499. X    case '[':
  500. X        for (pm++; *pm && *pm != ']'; pm++)
  501. X            continue;
  502. X        if (!*pm)
  503. X            pm--;
  504. X        continue;
  505. X    }
  506. X    if (brclev)
  507. X        goto doit;
  508. X    return (0);
  509. X}
  510. X
  511. static
  512. match(s, p)
  513. X    char *s, *p;
  514. X{
  515. X    register int c;
  516. X    register char *sentp;
  517. X    char sglobbed = globbed;
  518. X
  519. X    if (*s == '.' && *p != '.')
  520. X        return (0);
  521. X    sentp = entp;
  522. X    entp = s;
  523. X    c = amatch(s, p);
  524. X    entp = sentp;
  525. X    globbed = sglobbed;
  526. X    return (c);
  527. X}
  528. X
  529. static
  530. amatch(s, p)
  531. X    register char *s, *p;
  532. X{
  533. X    register int scc;
  534. X    int ok, lc;
  535. X    char *sgpathp;
  536. X    struct stat stb;
  537. X    int c, cc;
  538. X
  539. X    globbed = 1;
  540. X    for (;;) {
  541. X        scc = *s++ & TRIM;
  542. X        switch (c = *p++) {
  543. X
  544. X        case '{':
  545. X            return (execbrc(p - 1, s - 1));
  546. X
  547. X        case '[':
  548. X            ok = 0;
  549. X            lc = 077777;
  550. X            while (cc = *p++) {
  551. X                if (cc == ']') {
  552. X                    if (ok)
  553. X                        break;
  554. X                    return (0);
  555. X                }
  556. X                if (cc == '-') {
  557. X                    if (lc <= scc && scc <= *p++)
  558. X                        ok++;
  559. X                } else
  560. X                    if (scc == (lc = cc))
  561. X                        ok++;
  562. X            }
  563. X            if (cc == 0)
  564. X                if (ok)
  565. X                    p--;
  566. X                else
  567. X                    return 0;
  568. X            continue;
  569. X
  570. X        case '*':
  571. X            if (!*p)
  572. X                return (1);
  573. X            if (*p == '/') {
  574. X                p++;
  575. X                goto slash;
  576. X            }
  577. X            s--;
  578. X            do {
  579. X                if (amatch(s, p))
  580. X                    return (1);
  581. X            } while (*s++);
  582. X            return (0);
  583. X
  584. X        case 0:
  585. X            return (scc == 0);
  586. X
  587. X        default:
  588. X            if (c != scc)
  589. X                return (0);
  590. X            continue;
  591. X
  592. X        case '?':
  593. X            if (scc == 0)
  594. X                return (0);
  595. X            continue;
  596. X
  597. X        case '/':
  598. X            if (scc)
  599. X                return (0);
  600. slash:
  601. X            s = entp;
  602. X            sgpathp = gpathp;
  603. X            while (*s)
  604. X                addpath(*s++);
  605. X            addpath('/');
  606. X            if (util_stat(gpath, &stb) == 0 && isdir(stb))
  607. X                if (*p == 0) {
  608. X                    Gcat(gpath, "");
  609. X                    globcnt++;
  610. X                } else
  611. X                    expand(p);
  612. X            gpathp = sgpathp;
  613. X            *gpathp = 0;
  614. X            return (0);
  615. X        }
  616. X    }
  617. X}
  618. X
  619. static
  620. Gmatch(s, p)
  621. X    register char *s, *p;
  622. X{
  623. X    register int scc;
  624. X    int ok, lc;
  625. X    int c, cc;
  626. X
  627. X    for (;;) {
  628. X        scc = *s++ & TRIM;
  629. X        switch (c = *p++) {
  630. X
  631. X        case '[':
  632. X            ok = 0;
  633. X            lc = 077777;
  634. X            while (cc = *p++) {
  635. X                if (cc == ']') {
  636. X                    if (ok)
  637. X                        break;
  638. X                    return (0);
  639. X                }
  640. X                if (cc == '-') {
  641. X                    if (lc <= scc && scc <= *p++)
  642. X                        ok++;
  643. X                } else
  644. X                    if (scc == (lc = cc))
  645. X                        ok++;
  646. X            }
  647. X            if (cc == 0)
  648. X                if (ok)
  649. X                    p--;
  650. X                else
  651. X                    return 0;
  652. X            continue;
  653. X
  654. X        case '*':
  655. X            if (!*p)
  656. X                return (1);
  657. X            for (s--; *s; s++)
  658. X                if (Gmatch(s, p))
  659. X                    return (1);
  660. X            return (0);
  661. X
  662. X        case 0:
  663. X            return (scc == 0);
  664. X
  665. X        default:
  666. X            if ((c & TRIM) != scc)
  667. X                return (0);
  668. X            continue;
  669. X
  670. X        case '?':
  671. X            if (scc == 0)
  672. X                return (0);
  673. X            continue;
  674. X
  675. X        }
  676. X    }
  677. X}
  678. X
  679. static
  680. Gcat(s1, s2)
  681. X    register char *s1, *s2;
  682. X{
  683. X    register int len = strlen(s1) + strlen(s2) + 1;
  684. X
  685. X    if (len >= gnleft || gargc >= GAVSIZ - 1)
  686. X        globerr = "Arguments too long";
  687. X    else {
  688. X        gargc++;
  689. X        gnleft -= len;
  690. X        gargv[gargc] = 0;
  691. X        gargv[gargc - 1] = strspl(s1, s2);
  692. X    }
  693. X}
  694. X
  695. static
  696. addpath(c)
  697. X    char c;
  698. X{
  699. X
  700. X    if (gpathp >= lastgpathp)
  701. X        globerr = "Pathname too long";
  702. X    else {
  703. X        *gpathp++ = c;
  704. X        *gpathp = 0;
  705. X    }
  706. X}
  707. X
  708. static
  709. rscan(t, f)
  710. X    register char **t;
  711. X    int (*f)();
  712. X{
  713. X    register char *p, c;
  714. X
  715. X    while (p = *t++) {
  716. X        if (f == tglob)
  717. X            if (*p == '~')
  718. X                gflag |= 2;
  719. X            else if (eq(p, "{") || eq(p, "{}"))
  720. X                continue;
  721. X        while (c = *p++)
  722. X            (*f)(c);
  723. X    }
  724. X}
  725. X/*
  726. static
  727. scan(t, f)
  728. X    register char **t;
  729. X    int (*f)();
  730. X{
  731. X    register char *p, c;
  732. X
  733. X    while (p = *t++)
  734. X        while (c = *p)
  735. X            *p++ = (*f)(c);
  736. X} */
  737. X
  738. static
  739. tglob(c)
  740. X    register char c;
  741. X{
  742. X
  743. X    if (any(c, globchars))
  744. X        gflag |= c == '{' ? 2 : 1;
  745. X    return (c);
  746. X}
  747. X/*
  748. static
  749. trim(c)
  750. X    char c;
  751. X{
  752. X
  753. X    return (c & TRIM);
  754. X} */
  755. X
  756. X
  757. letter(c)
  758. X    register char c;
  759. X{
  760. X
  761. X    return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
  762. X}
  763. X
  764. digit(c)
  765. X    register char c;
  766. X{
  767. X
  768. X    return (c >= '0' && c <= '9');
  769. X}
  770. X
  771. any(c, s)
  772. X    register int c;
  773. X    register char *s;
  774. X{
  775. X
  776. X    while (*s)
  777. X        if (*s++ == c)
  778. X            return(1);
  779. X    return(0);
  780. X}
  781. blklen(av)
  782. X    register char **av;
  783. X{
  784. X    register int i = 0;
  785. X
  786. X    while (*av++)
  787. X        i++;
  788. X    return (i);
  789. X}
  790. X
  791. char **
  792. blkcpy(oav, bv)
  793. X    char **oav;
  794. X    register char **bv;
  795. X{
  796. X    register char **av = oav;
  797. X
  798. X    while (*av++ = *bv++)
  799. X        continue;
  800. X    return (oav);
  801. X}
  802. X
  803. blkfree(av0)
  804. X    char **av0;
  805. X{
  806. X    register char **av = av0;
  807. X
  808. X    while (*av)
  809. X        free(*av++);
  810. X    free((char *)av0);
  811. X}
  812. X
  813. static
  814. char *
  815. strspl(cp, dp)
  816. X    register char *cp, *dp;
  817. X{
  818. X    register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));
  819. X
  820. X    if (ep == (char *)0)
  821. X        { perror("Out of memory 1"); exit(1); }
  822. X    (void) strcpy(ep, cp);
  823. X    (void) strcat(ep, dp);
  824. X    return (ep);
  825. X}
  826. X
  827. char **
  828. copyblk(v)
  829. X    register char **v;
  830. X{
  831. X    register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
  832. X                        sizeof(char **)));
  833. X    if (nv == (char **)0)
  834. X        { perror("Out of memory 2"); exit(2); }
  835. X
  836. X    return (blkcpy(nv, v));
  837. X}
  838. X
  839. static
  840. char *
  841. strend(cp)
  842. X    register char *cp;
  843. X{
  844. X
  845. X    while (*cp)
  846. X        cp++;
  847. X    return (cp);
  848. X}
  849. X/*
  850. X * Extract a home directory from the password file
  851. X * The argument points to a buffer where the name of the
  852. X * user whose home directory is sought is currently.
  853. X * We write the home directory of the user back there.
  854. X */
  855. gethdir(home)
  856. X    char *home;
  857. X{
  858. X}
  859. END_OF_FILE
  860. if test 10080 -ne `wc -c <'bsd_src/glob.c'`; then
  861.     echo shar: \"'bsd_src/glob.c'\" unpacked with wrong size!
  862. fi
  863. # end of 'bsd_src/glob.c'
  864. fi
  865. if test -f 'bsd_src/print.c' -a "${1}" != "-c" ; then 
  866.   echo shar: Will not clobber existing file \"'bsd_src/print.c'\"
  867. else
  868. echo shar: Extracting \"'bsd_src/print.c'\" \(4381 characters\)
  869. sed "s/^X//" >'bsd_src/print.c' <<'END_OF_FILE'
  870. X/*
  871. X * Copyright (c) 1989 The Regents of the University of California.
  872. X * All rights reserved.
  873. X *
  874. X * This code is derived from software contributed to Berkeley by
  875. X * Michael Fischbein.
  876. X *
  877. X * Redistribution and use in source and binary forms are permitted
  878. X * provided that: (1) source distributions retain this entire copyright
  879. X * notice and comment, and (2) distributions including binaries display
  880. X * the following acknowledgement:  ``This product includes software
  881. X * developed by the University of California, Berkeley and its contributors''
  882. X * in the documentation or other materials provided with the distribution
  883. X * and in all advertising materials mentioning features or use of this
  884. X * software. Neither the name of the University nor the names of its
  885. X * contributors may be used to endorse or promote products derived
  886. X * from this software without specific prior written permission.
  887. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  888. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  889. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  890. X */
  891. X
  892. X#ifndef lint
  893. static char sccsid[] = "@(#)print.c    5.22 (Berkeley) 5/10/90";
  894. X#endif /* not lint */
  895. X
  896. X#include <sys/types.h>
  897. X#include <sys/param.h>
  898. X#include <sys/stat.h>
  899. X#include <stdio.h>
  900. X#include <grp.h>
  901. X#include <pwd.h>
  902. X#include <utmp.h>
  903. X#include "ls.h"
  904. X#include "tweak.h"
  905. X
  906. X#define BLK(A) (((A)+1023)/1024)
  907. X
  908. printscol(stats, num)
  909. X    register LS *stats;
  910. X    register int num;
  911. X{
  912. X    for (; num--; ++stats) {
  913. X        (void)printaname(stats);
  914. X        (void)putchar('\n');
  915. X    }
  916. X}
  917. X
  918. printlong(stats, num)
  919. X    LS *stats;
  920. X    register int num;
  921. X{
  922. X    extern int errno;
  923. X    char *modep;
  924. X
  925. X    if (f_total)
  926. X        (void)printf("total %lu\n", stats[0].lstat.st_btotal);
  927. X    for (; num--; ++stats) {
  928. X        if (f_inode) (void)printf("%6lu ", stats->lstat.st_ino);
  929. X        if (f_size ) (void)printf("%4ld ", BLK(stats->lstat.st_size));
  930. X        modep = ((S_IFDIR & stats->lstat.st_mode)) ? "drwxrwxrwx"
  931. X                            : "-rw-rw-rw-" ;
  932. X
  933. X        (void)printf("%s %3u %-*s ",
  934. X            modep, stats->lstat.st_nlink, 8, "nobody");
  935. X        if (f_group)
  936. X            (void)printf("%-*s ", 8, "nobody");
  937. X        else
  938. X            (void)printf("%8ld ", stats->lstat.st_size);
  939. X        if (f_accesstime)
  940. X            printtime(stats->lstat.st_atime);
  941. X        else if (f_statustime)
  942. X            printtime(stats->lstat.st_ctime);
  943. X        else
  944. X            printtime(stats->lstat.st_mtime);
  945. X        (void)printf("%s", stats->name);
  946. X        if (f_type)
  947. X            (void)printtype(stats->lstat.st_mode);
  948. X        (void)putchar('\n');
  949. X    }
  950. X}
  951. X
  952. X#define    TAB    8
  953. X
  954. printcol(stats, num)
  955. X    LS *stats;
  956. X    int num;
  957. X{
  958. X    extern int termwidth;
  959. X    register int base, chcnt, cnt, col, colwidth;
  960. X    int endcol, numcols, numrows, row;
  961. X
  962. X    colwidth = stats[0].lstat.st_maxlen;
  963. X    if (f_inode)
  964. X        colwidth += 6;
  965. X    if (f_size)
  966. X        colwidth += 5;
  967. X    if (f_type)
  968. X        colwidth += 1;
  969. X
  970. X    colwidth = (colwidth + TAB) & ~(TAB - 1);
  971. X    if (termwidth < 2 * colwidth) {
  972. X        printscol(stats, num);
  973. X        return;
  974. X    }
  975. X
  976. X    numcols = termwidth / colwidth;
  977. X    numrows = num / numcols;
  978. X    if (num % numcols)
  979. X        ++numrows;
  980. X
  981. X    if (f_size && f_total)
  982. X        (void)printf("total %lu\n", stats[0].lstat.st_btotal);
  983. X    for (row = 0; row < numrows; ++row) {
  984. X        endcol = colwidth;
  985. X        for (base = row, chcnt = col = 0; col < numcols; ++col) {
  986. X            chcnt += printaname(stats + base);
  987. X            if ((base += numrows) >= num)
  988. X                break;
  989. X            while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
  990. X                (void)putchar('\t');
  991. X                chcnt = cnt;
  992. X            }
  993. X            endcol += colwidth;
  994. X        }
  995. X        putchar('\n');
  996. X    }
  997. X}
  998. X
  999. X/*
  1000. X * print [inode] [size] name
  1001. X * return # of characters printed, no trailing characters
  1002. X */
  1003. printaname(lp)
  1004. X    LS *lp;
  1005. X{
  1006. X    int chcnt;
  1007. X
  1008. X    chcnt = 0;
  1009. X
  1010. X    if (f_inode)
  1011. X    {
  1012. X        printf("%5lu ", lp->lstat.st_ino);
  1013. X        chcnt += 6;
  1014. X    }
  1015. X
  1016. X    if (f_size)
  1017. X    {
  1018. X        printf("%4ld ", BLK(lp->lstat.st_size));
  1019. X        chcnt += 5;
  1020. X    }
  1021. X
  1022. X    printf("%s", lp->name); chcnt += strlen(lp->name);
  1023. X
  1024. X    if (f_type)
  1025. X    {
  1026. X        chcnt += printtype(lp->lstat.st_mode);
  1027. X    }
  1028. X
  1029. X    return(chcnt);
  1030. X}
  1031. X
  1032. printtime(ftime)
  1033. X    time_t ftime;
  1034. X{
  1035. X    int i;
  1036. X    char *longstring, *ctime();
  1037. X    time_t time();
  1038. X
  1039. X    longstring = ctime((long *)&ftime);
  1040. X    for (i = 4; i < 11; ++i)
  1041. X        (void)putchar(longstring[i]);
  1042. X
  1043. X#define    SIXMONTHS    ((365 / 2) * 24 * 60 * 60)
  1044. X    if (ftime + SIXMONTHS > time((time_t *)NULL))
  1045. X        for (i = 11; i < 16; ++i)
  1046. X            (void)putchar(longstring[i]);
  1047. X    else {
  1048. X        (void)putchar(' ');
  1049. X        for (i = 20; i < 24; ++i)
  1050. X            (void)putchar(longstring[i]);
  1051. X    }
  1052. X    (void)putchar(' ');
  1053. X}
  1054. X
  1055. printtype(mode)
  1056. X    mode_t mode;
  1057. X{
  1058. X    switch(mode & S_IFMT) {
  1059. X    case S_IFDIR:
  1060. X        (void)putchar('/');
  1061. X        return(1);
  1062. X    }
  1063. X    return(0);
  1064. X}
  1065. END_OF_FILE
  1066. if test 4381 -ne `wc -c <'bsd_src/print.c'`; then
  1067.     echo shar: \"'bsd_src/print.c'\" unpacked with wrong size!
  1068. fi
  1069. # end of 'bsd_src/print.c'
  1070. fi
  1071. if test -f 'client_util.c' -a "${1}" != "-c" ; then 
  1072.   echo shar: Will not clobber existing file \"'client_util.c'\"
  1073. else
  1074. echo shar: Extracting \"'client_util.c'\" \(9556 characters\)
  1075. sed "s/^X//" >'client_util.c' <<'END_OF_FILE'
  1076. X    /*********************************************************************\
  1077. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1078. X    *                                                                     *
  1079. X    *  You may copy or modify this file in any manner you wish, provided  *
  1080. X    *  that this notice is always included, and that you hold the author  *
  1081. X    *  harmless for any loss or damage resulting from the installation or *
  1082. X    *  use of this software.                                              *
  1083. X    \*********************************************************************/
  1084. X
  1085. X#include "client_def.h"
  1086. X
  1087. extern char *realloc(), *malloc(), *getenv();
  1088. extern int errno;
  1089. X
  1090. static int env_dir_malloced = 0;
  1091. char *env_dir = "/";
  1092. char *env_myport;
  1093. char *env_host;
  1094. char *env_port;
  1095. X
  1096. char *util_abs_path(s2)
  1097. X    char *s2;
  1098. X{
  1099. X    char *path, *s, *d, *t;
  1100. X
  1101. X    if(!env_dir) env_dir = "";
  1102. X    if(!s2) s2 = "";
  1103. X
  1104. X    if(*s2 == '/')
  1105. X    {
  1106. X    path = malloc(strlen(s2)+2);
  1107. X    sprintf(path,"/%s",s2);
  1108. X    } else
  1109. X    {
  1110. X    path = malloc(strlen(env_dir)+strlen(s2)+3);
  1111. X    sprintf(path,"/%s/%s",env_dir,s2);
  1112. X    }
  1113. X
  1114. X    for(t = path; *t; )
  1115. X    {
  1116. X    if(t[0] == '/')
  1117. X    {
  1118. X        while(t[1] == '/') for(d = t, s = t+1; *d++ = *s++; );
  1119. X        if(t != path && t[1] == 0) { t[0] = 0; return(path); }
  1120. X    }
  1121. X    if(t[0] == '.' && t[1] == '.')
  1122. X    {
  1123. X        if(t-1 == path && t[2] ==  0 ) { *t = 0; return(path); }
  1124. X        if(t-1 == path && t[2] == '/')
  1125. X        {
  1126. X        for(d = t, s = t + 3; *d++ = *s++; );
  1127. X        continue;
  1128. X        }
  1129. X        if(t[-1] == '/' && (t[2] == '/' || t[2] ==  0))
  1130. X        {
  1131. X        s = t + 2;    /* point to either slash or nul */
  1132. X        t -= 2;        /* guaranteed that t >= path here */
  1133. X        while(t > path && t[0] != '/') t--;
  1134. X        if(t != path || *s == '/') { for(d = t; *d++ = *s++; ); }
  1135. X                      else { t[1] = 0; return(path);    }
  1136. X        continue;
  1137. X        }
  1138. X    }
  1139. X    if(t[0] == '.')
  1140. X    {
  1141. X        if(t-1 == path && t[1] ==  0 ) { *t = 0; return(path); }
  1142. X        if(t-1 == path && t[1] == '/')
  1143. X        {
  1144. X        for(d = t, s = t + 2; *d++ = *s++; );
  1145. X        continue;
  1146. X        }
  1147. X        if(t[-1] == '/' && (t[1] == '/' || t[1] ==  0))
  1148. X        {
  1149. X        s = t + 1;    /* point to either slash or nul */
  1150. X        for(d = t-1; *d++ = *s++; ); 
  1151. X        t--;
  1152. X        continue;
  1153. X        }
  1154. X    }
  1155. X    t++;
  1156. X    }
  1157. X    return(path);
  1158. X}
  1159. X
  1160. char *util_getwd(p)
  1161. X    char *p;
  1162. X{
  1163. X    if(p) strcpy(p,env_dir);
  1164. X    return(p);
  1165. X}
  1166. X
  1167. RDIRENT **get_dir_blk(path)
  1168. X    char *path;
  1169. X{
  1170. X    RDIRENT **dp;
  1171. X    char *p1, *p2;
  1172. X    unsigned long pos;
  1173. X    int cnt, k, rem;
  1174. X    UBUF *ub;
  1175. X    char *fpath;
  1176. X
  1177. X    fpath = util_abs_path(path);
  1178. X
  1179. X    for(pos = 0, cnt = 0; ; )
  1180. X    {
  1181. X    ub = client_interact(CC_GET_DIR,pos, strlen(fpath),fpath+1, 0,NULLP);
  1182. X
  1183. X    if(ub->cmd == CC_ERR)
  1184. X    {
  1185. X        fprintf(stderr,"directory reading error: %s\n",ub->buf);
  1186. X        free(fpath); return((RDIRENT **) 0);
  1187. X    }
  1188. X
  1189. X    for(p2 = ub->buf, rem = ub->len, k = 0; ; k++)
  1190. X    {
  1191. X        if(rem < RDHSIZE) break;
  1192. X        if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
  1193. X        if(((RDIRENT *) p2)->type == RDTYPE_END ) { k++; break; }
  1194. X        p2 += RDHSIZE; rem -= (RDHSIZE+1);
  1195. X        while(*p2++             ) {       rem--; }
  1196. X        while((p2 - ub->buf) & 3) { p2++; rem--; }
  1197. X    }
  1198. X
  1199. X    p1 = malloc(p2-ub->buf);
  1200. X    if(cnt) dp = (RDIRENT **) realloc(dp,(cnt+k+1)*sizeof(RDIRENT *));
  1201. X       else dp = (RDIRENT **)  malloc(   (cnt+k+1)*sizeof(RDIRENT *));
  1202. X
  1203. X    if(!p1 || !dp) { free(fpath);
  1204. X              fputs("directory reading out of memory\n",stderr);
  1205. X              return((RDIRENT **) 0); }
  1206. X
  1207. X    for(p2 = ub->buf, rem = ub->len; ; cnt++)
  1208. X    {
  1209. X        if(rem < RDHSIZE) break;
  1210. X        if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
  1211. X        if(((RDIRENT *) p2)->type == RDTYPE_END )
  1212. X                        { dp[cnt] = 0; return(dp); }
  1213. X        dp[cnt] = (RDIRENT *) p1;
  1214. X        ((RDIRENT *) p1)->time = ntohl(((RDIRENT *) p2)->time);
  1215. X        ((RDIRENT *) p1)->size = ntohl(((RDIRENT *) p2)->size);
  1216. X        ((RDIRENT *) p1)->type =       ((RDIRENT *) p2)->type ;
  1217. X
  1218. X        p2 += RDHSIZE; p1 += RDHSIZE; rem -= (RDHSIZE+1);
  1219. X        while(*p1++ = *p2++     ) {            rem--; }
  1220. X        while((p2 - ub->buf) & 3) { p2++; p1++; rem--; }
  1221. X    }
  1222. X
  1223. X    if(ub->len != UBUF_SPACE) { dp[cnt] = 0; return(dp); }
  1224. X    pos += ub->len;
  1225. X    }
  1226. X}
  1227. X
  1228. util_download(path,fp)
  1229. X    char *path;
  1230. X    FILE *fp;
  1231. X{   
  1232. X    unsigned long pos;
  1233. X    unsigned tmax, tcnt, wrote;
  1234. X    UBUF *ub;
  1235. X    char *fpath;
  1236. X    fpath = util_abs_path(path);
  1237. X    for(tmax = 1, tcnt = 0, pos = 0; ; )
  1238. X    {   
  1239. X        ub = client_interact(CC_GET_FILE,pos, strlen(fpath),fpath+1, 0,NULLP);
  1240. X
  1241. X    if(client_trace && (++tcnt >= tmax))
  1242. X    {
  1243. X        if(tmax < 16) tmax <<= 1; else tcnt = 0;
  1244. X        fprintf(stderr,"\r%luk  ",pos>>10);
  1245. X        fflush(stderr);
  1246. X    }
  1247. X
  1248. X        if(ub->cmd == CC_ERR)
  1249. X        {    
  1250. X            fprintf(stderr,"downloading %s: %s\n",path,ub->buf);
  1251. X        free(fpath); return(-1); 
  1252. X        }   
  1253. X        wrote = fwrite(ub->buf,1,ub->len,fp);
  1254. X        pos  += wrote;
  1255. X        if(ub->len < UBUF_SPACE || ub->len != wrote) break;
  1256. X    }
  1257. X
  1258. X    if(client_trace) { fprintf(stderr,"\r%luk : %s \n",pos>>10,path);
  1259. X               fflush(stderr); }
  1260. X
  1261. X    free(fpath); return(0);
  1262. X}
  1263. X
  1264. util_upload(path,fp)
  1265. X    char *path;
  1266. X    FILE *fp;
  1267. X{   
  1268. X    unsigned long pos;
  1269. X    unsigned bytes, first, tmax, tcnt;
  1270. X    char *fpath, buf[UBUF_SPACE];
  1271. X    UBUF *ub;
  1272. X    fpath = util_abs_path(path);
  1273. X    for(tmax = 1, tcnt = 0, pos = 0, first = 1; ; first = 0)
  1274. X    {   
  1275. X    if((bytes = fread(buf,1,sizeof(buf),fp)) || first)
  1276. X    {
  1277. X        ub = client_interact(CC_UP_LOAD,pos, bytes,buf, 0,NULLP);
  1278. X        if(client_trace && (++tcnt >= tmax))
  1279. X        {
  1280. X        if(tmax < 16) tmax <<= 1; else tcnt = 0;
  1281. X        fprintf(stderr,"\r%luk ",pos>>10);
  1282. X        fflush(stderr);
  1283. X        }
  1284. X
  1285. X    } else
  1286. X    {
  1287. X        ub = client_interact(CC_INSTALL,pos,strlen(fpath),fpath+1,0,NULLP);
  1288. X    }
  1289. X        if(ub->cmd == CC_ERR)
  1290. X        {    
  1291. X            fprintf(stderr,"uploading %s: %s\n",path,ub->buf);
  1292. X        free(fpath); return(1); 
  1293. X        }   
  1294. X    if(!bytes && !first) break;
  1295. X        pos += bytes;
  1296. X    }
  1297. X
  1298. X    if(client_trace) { fprintf(stderr,"\r%luk : %s \n",pos>>10,path);
  1299. X               fflush(stderr); }
  1300. X
  1301. X    free(fpath); return(0);
  1302. X}
  1303. X
  1304. util_get_env()
  1305. X{
  1306. X    if(!(env_host = getenv("FSP_HOST")))
  1307. X        { fputs("Env var FSP_HOST not defined\n",stderr); exit(1); }
  1308. X    if(!(env_port = getenv("FSP_PORT")))
  1309. X        { fputs("Env var FSP_PORT not defined\n",stderr); exit(1); }
  1310. X    if(!(env_dir  = getenv("FSP_DIR")))
  1311. X        { fputs("Env var FSP_DIR not defined\n",stderr); exit(1); }
  1312. X    if(!(env_myport  = getenv("FSP_LOCALPORT")))
  1313. X        { fputs("Env var FSP_LOCALPORT not defined\n",stderr); exit(1); }
  1314. X
  1315. X    client_trace  = !!getenv("FSP_TRACE");
  1316. X}
  1317. X
  1318. client_intr()
  1319. X{
  1320. X    switch(client_intr_state)
  1321. X    {
  1322. X    case 0: exit(2);
  1323. X    case 1: client_intr_state = 2; break;
  1324. X    case 2: exit(3);
  1325. X    }
  1326. X}
  1327. X
  1328. env_client()
  1329. X{
  1330. X    util_get_env();
  1331. X    init_client(env_host,atoi(env_port),atoi(env_myport));
  1332. X    signal(SIGINT,client_intr);
  1333. X}
  1334. X
  1335. X/*****************************************************************************/
  1336. X
  1337. static DDLIST *ddroot = 0;
  1338. X
  1339. RDIR *util_opendir(path)
  1340. X    char *path;
  1341. X{
  1342. X    char *fpath;
  1343. X    RDIRENT **dep;
  1344. X    DDLIST   *ddp;
  1345. X    RDIR   *rdirp;
  1346. X
  1347. X    fpath = util_abs_path(path);
  1348. X
  1349. X    for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
  1350. X
  1351. X    if(!ddp)
  1352. X    {
  1353. X    if(!(dep = get_dir_blk(fpath))) return((RDIR *) 0);
  1354. X    ddp = (DDLIST *) malloc(sizeof(DDLIST));
  1355. X    ddp->dep_root = dep;
  1356. X    ddp->path     = fpath;
  1357. X    ddp->ref_cnt  = 0;
  1358. X    ddp->next     = ddroot;
  1359. X    ddroot        = ddp;
  1360. X
  1361. X    } else free(fpath);
  1362. X
  1363. X    ddp->ref_cnt++;
  1364. X
  1365. X    rdirp = (RDIR *) malloc(sizeof(RDIR));
  1366. X    rdirp->ddp = ddp;
  1367. X    rdirp->dep = ddp->dep_root;
  1368. X    return(rdirp);
  1369. X}
  1370. X
  1371. util_closedir(rdirp)
  1372. X    RDIR *rdirp;
  1373. X{
  1374. X    rdirp->ddp->ref_cnt--;
  1375. X    free(rdirp);
  1376. X}
  1377. X
  1378. rdirent *util_readdir(rdirp)
  1379. X    RDIR *rdirp;
  1380. X{
  1381. X    static rdirent rde;
  1382. X    RDIRENT **dep;
  1383. X
  1384. X    dep = rdirp->dep;
  1385. X
  1386. X    if(!*dep) return((rdirent *) 0);
  1387. X
  1388. X    rde.d_fileno = 10;
  1389. X    rde.d_reclen = 10;
  1390. X    rde.d_namlen = strlen((*dep)->name);
  1391. X    rde.d_name   = (*dep)->name;
  1392. X    rdirp->dep   = dep+1;
  1393. X
  1394. X    return(&rde);
  1395. X}
  1396. X
  1397. util_split_path(path,p1,p2,p3)
  1398. X    char *path, **p1, **p2, **p3;
  1399. X{
  1400. X    char *s;
  1401. X    static char junk;
  1402. X
  1403. X    *p1 = "/";
  1404. X    if(*path == '/') { *p2 =  path; *p3 = path+1; }
  1405. X        else { *p2 = &junk; *p3 = path  ; }
  1406. X
  1407. X    for(s = *p3; *s; s++)
  1408. X    {
  1409. X    if(*s == '/')
  1410. X    {
  1411. X        *p1 = path;
  1412. X        *p2 = s;
  1413. X        *p3 = s+1;
  1414. X    }
  1415. X    }
  1416. X
  1417. X    return(1);
  1418. X}
  1419. X
  1420. util_stat(path,sbuf)
  1421. X    char *path;
  1422. X    struct stat *sbuf;
  1423. X{
  1424. X    RDIR *drp;
  1425. X    RDIRENT **dep;
  1426. X    char *fpath, *ppath, *p1, *pfile;
  1427. X
  1428. X    fpath = util_abs_path(path);
  1429. X
  1430. X    if(!strcmp(fpath,env_dir))
  1431. X    {
  1432. X    ppath = fpath;
  1433. X    pfile = ".";
  1434. X
  1435. X    } else
  1436. X    {
  1437. X    util_split_path(fpath,&ppath,&p1,&pfile); *p1 = 0;
  1438. X    }
  1439. X
  1440. X    if(drp = util_opendir(ppath))
  1441. X    {
  1442. X    for(dep = drp->dep; *dep; dep++)
  1443. X    {
  1444. X        if(!strcmp((*dep)->name,pfile))
  1445. X        {
  1446. X        if((*dep)->type & RDTYPE_DIR) sbuf->st_mode = 0777 | S_IFDIR;
  1447. X                     else sbuf->st_mode = 0666 | S_IFREG;
  1448. X
  1449. X        if((*dep)->type & RDTYPE_DIR) sbuf->st_nlink  = 2;
  1450. X                     else sbuf->st_nlink  = 1;
  1451. X        sbuf->st_uid    = 0;
  1452. X        sbuf->st_gid    = 0;
  1453. X        sbuf->st_size   = (*dep)->size;
  1454. X        sbuf->st_atime  = (*dep)->time;
  1455. X        sbuf->st_mtime  = (*dep)->time;
  1456. X        sbuf->st_ctime  = (*dep)->time;
  1457. X        util_closedir(drp); free(fpath); return(0);
  1458. X        }
  1459. X    }
  1460. X    util_closedir(drp);
  1461. X    }
  1462. X
  1463. X    free(fpath); errno = ENOENT; return(-1);
  1464. X}
  1465. X
  1466. util_cd(p)
  1467. X    char *p;
  1468. X{
  1469. X    char *fpath;
  1470. X    UBUF *ub;
  1471. X    DDLIST   *ddp;
  1472. X
  1473. X    fpath = util_abs_path(p);
  1474. X    for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
  1475. X
  1476. X    if(!ddp)
  1477. X    {
  1478. X    ub = client_interact(CC_GET_DIR,0L, strlen(fpath),fpath+1, 0,NULLP);
  1479. X
  1480. X    if(ub->cmd == CC_ERR)
  1481. X    {
  1482. X        free(fpath);
  1483. X        fprintf(stderr,"cd error: %s\n",ub->buf);
  1484. X        errno = EACCES;
  1485. X        return(-1);
  1486. X    }
  1487. X    }
  1488. X
  1489. X    if(env_dir_malloced) free(env_dir);
  1490. X    env_dir_malloced = 1;
  1491. X    env_dir = fpath;
  1492. X    return(0);
  1493. X}
  1494. END_OF_FILE
  1495. if test 9556 -ne `wc -c <'client_util.c'`; then
  1496.     echo shar: \"'client_util.c'\" unpacked with wrong size!
  1497. fi
  1498. # end of 'client_util.c'
  1499. fi
  1500. if test -f 'common_def.h' -a "${1}" != "-c" ; then 
  1501.   echo shar: Will not clobber existing file \"'common_def.h'\"
  1502. else
  1503. echo shar: Extracting \"'common_def.h'\" \(4903 characters\)
  1504. sed "s/^X//" >'common_def.h' <<'END_OF_FILE'
  1505. X    /*********************************************************************\
  1506. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1507. X    *                                                                     *
  1508. X    *  You may copy or modify this file in any manner you wish, provided  *
  1509. X    *  that this notice is always included, and that you hold the author  *
  1510. X    *  harmless for any loss or damage resulting from the installation or *
  1511. X    *  use of this software.                                              *
  1512. X    \*********************************************************************/
  1513. X
  1514. X#include <stdio.h>
  1515. X#include <sys/param.h>
  1516. X#include <sys/types.h>
  1517. X#include <dirent.h>
  1518. X#include <errno.h>
  1519. X#include <sys/socket.h>
  1520. X#include <netinet/in.h>
  1521. X#include <sys/stat.h>
  1522. X#include <sys/time.h>
  1523. X#include <fcntl.h>
  1524. X#include <signal.h>
  1525. X
  1526. X/****************************************************************************
  1527. X*  UBUF is the structure of message exchanged between server and clients. 
  1528. X*
  1529. X*    The 'buf' part of the buffer is variable lenght up to max of 1024.
  1530. X*    The 'key' field is used by the server for sequence identification.
  1531. X*    The 'seq' field is used by the client for sequence identification.
  1532. X*
  1533. X*  Client's message to server contain a key value that is the same as the
  1534. X*  key value of the previous message received from the server.  Similarly,
  1535. X*  the server's message to client contains a seq value that is the same
  1536. X*  as the seq value of the previous message from the client. 
  1537. X*
  1538. X*  The buf field is logically partitioned into two parts by the len field.
  1539. X*  The len field indicate the size of the first part of the buffer starting
  1540. X*  at buf[0].  The rest of the buffer is the second field.  In some cases
  1541. X*  both fields can contain information.
  1542. X*
  1543. X****************************************************************************/
  1544. X
  1545. X#define UBUF_HSIZE 12                           /* 12 bytes for the header */
  1546. X#define UBUF_SPACE 1024                    /* maximum payload.        */
  1547. X
  1548. typedef struct UBUF {            char   cmd;  /* message code.             */
  1549. X                        unsigned char   sum;  /* message checksum.         */
  1550. X                        unsigned short  key;  /* message key.              */
  1551. X                        unsigned short  seq;  /* message sequence number.  */
  1552. X                        unsigned short  len;  /* number of bytes in buf 1. */
  1553. X                        unsigned long   pos;  /* location in the file.     */
  1554. X
  1555. X                        char   buf[UBUF_SPACE];
  1556. X                    } UBUF;
  1557. X
  1558. X/* definition of cmd */
  1559. X
  1560. X#define CC_VERSION    0x10    /* return server's version string.    */
  1561. X#define CC_ERR          0x40    /* error response from server.          */
  1562. X#define CC_GET_DIR      0x41    /* get a directory listing.             */
  1563. X#define CC_GET_FILE     0x42    /* get a file.                          */
  1564. X#define CC_UP_LOAD      0x43    /* open a file for writing.             */
  1565. X#define CC_INSTALL      0x44    /* close a file opened for writing.     */
  1566. X#define CC_DEL_FILE     0x45    /* delete a file.                       */
  1567. X#define CC_DEL_DIR      0x46    /* delete a directory.                  */
  1568. X#define CC_GET_PRO      0x47    /* get directory protection.            */
  1569. X#define CC_SET_PRO      0x48    /* set directory protection.            */
  1570. X#define CC_MAKE_DIR     0x49    /* create a directory.                  */
  1571. X#define CC_BYE          0x4A    /* finish a session.                    */
  1572. X
  1573. X/****************************************************************************
  1574. X*  RDIRENT is the structure of a directory entry contained in a .FSP_CONTENT
  1575. X*  file.  Each entry contains a 4 bytes quantity 'time', a 4 bytes quentity
  1576. X*  'size', and 1 byte of 'type'.  Then followed by x number of bytes of
  1577. X*  'name'.  'name' is null terminated.  Then followed by enough number of
  1578. X*  padding to fill to an 4-byte boundary.  At this point, if the next entry
  1579. X*  to follow will spread across 1k boundary, then two possible things will
  1580. X*  happen.  1) if the header fits between this entry and the 1k boundary,
  1581. X*  a complete header will be filled in with a 'type' set to RDTYPE_SKIP.
  1582. X*  And then enough bytes to padd to 1k boundary.  2) if the header does
  1583. X*  not fit, then simply pad to the 1k boundary.  This will make sure that
  1584. X*  messages carrying directory information carry only complete directory
  1585. X*  entries and no fragmented entries.  The last entry is type RDTYPE_END.
  1586. X****************************************************************************/
  1587. X
  1588. X#define RDHSIZE (2*sizeof(unsigned long)+sizeof(unsigned char))
  1589. X
  1590. typedef struct RDIRENT { unsigned long  time;
  1591. X                         unsigned long  size;
  1592. X                         unsigned char  type;
  1593. X                         char        name[1]; } RDIRENT;
  1594. X
  1595. X#define RDTYPE_END      0x00
  1596. X#define RDTYPE_FILE     0x01
  1597. X#define RDTYPE_DIR      0x02
  1598. X#define RDTYPE_SKIP     0x2A
  1599. X
  1600. X#define NULLP ((char *) 0)
  1601. END_OF_FILE
  1602. if test 4903 -ne `wc -c <'common_def.h'`; then
  1603.     echo shar: \"'common_def.h'\" unpacked with wrong size!
  1604. fi
  1605. # end of 'common_def.h'
  1606. fi
  1607. if test -f 'server_host.c' -a "${1}" != "-c" ; then 
  1608.   echo shar: Will not clobber existing file \"'server_host.c'\"
  1609. else
  1610. echo shar: Extracting \"'server_host.c'\" \(4133 characters\)
  1611. sed "s/^X//" >'server_host.c' <<'END_OF_FILE'
  1612. X    /*********************************************************************\
  1613. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1614. X    *                                                                     *
  1615. X    *  You may copy or modify this file in any manner you wish, provided  *
  1616. X    *  that this notice is always included, and that you hold the author  *
  1617. X    *  harmless for any loss or damage resulting from the installation or *
  1618. X    *  use of this software.                                              *
  1619. X    \*********************************************************************/
  1620. X
  1621. X#include "server_def.h"
  1622. X
  1623. X/****************************************************************************
  1624. X* This file contains routines to maintain client database.
  1625. X****************************************************************************/
  1626. X
  1627. extern char *realloc(), *malloc(), *ctime();
  1628. X
  1629. static HTAB     *htab;        /* client data base.            */
  1630. static unsigned  hcnt;        /* number of clients.            */
  1631. static unsigned  htot = 0;    /* available entries in the data base.    */
  1632. static HTAB     hzero;
  1633. X
  1634. X#define HALLOC_SIZE 30
  1635. X
  1636. X/****************************************************************************
  1637. X* Returns an entry from the database corresponding to to the inet number.
  1638. X* A new entry is created is it is not found.
  1639. X* The database is a linear array of sorted structures.
  1640. X* Entries are searched using binary search on the array.
  1641. X****************************************************************************/
  1642. X
  1643. HTAB *find_host(inet_num)
  1644. X    unsigned long inet_num;
  1645. X{
  1646. X    unsigned      l, h, m, i;
  1647. X    unsigned long inum;
  1648. X    HTAB      *hs, *hd;
  1649. X
  1650. X    for(l = 0, h = hcnt-1; (m = (l + h) >> 1) != l; )    /* binary search */
  1651. X    {
  1652. X    inum = htab[m].inet_num;
  1653. X    if(inum > inet_num) h = m; else
  1654. X    if(inum < inet_num) l = m; else { htab[m].acc_cnt++; return(htab+m); }
  1655. X    }
  1656. X
  1657. X    if(htab[m].inet_num < inet_num) m++;  /* locate first entry that is > */
  1658. X
  1659. X    if((hcnt+1) > htot)            /* need more space */
  1660. X    {
  1661. X    htot += HALLOC_SIZE;        /* add HALLOC_SIZE entries at a time */
  1662. X
  1663. X    if(!(htab = (HTAB *) realloc(htab,sizeof(HTAB)*htot)))
  1664. X                    { perror("grow_htab realloc"); exit(1); }
  1665. X    }
  1666. X
  1667. X    for(i = hcnt-m, hs = htab+hcnt, hd=htab+hcnt+1; i--; *--hd = *--hs);
  1668. X
  1669. X    htab[m]=hzero;
  1670. X    htab[m].inet_num = inet_num;
  1671. X    htab[m].last_key = get_next_key()  ;
  1672. X    htab[m].next_key = get_next_key()+1;
  1673. X    hcnt++;
  1674. X    return(htab+m);
  1675. X}
  1676. X
  1677. X/****************************************************************************
  1678. X* Write out the client table in the .HTAB_DUMP file.
  1679. X****************************************************************************/
  1680. X
  1681. dump_htab()
  1682. X{
  1683. X    int i;
  1684. X    FILE *fp;
  1685. X    HTAB *hp;
  1686. X
  1687. X    if(!(fp = fopen(".HTAB_DUMP","w"))) return;
  1688. X
  1689. X    for(i = hcnt-2, hp = htab+1; i--; hp++)
  1690. X    {
  1691. X    fprintf(fp,"%d.%d.%d.%d\t%5d %c %s",
  1692. X                ((unsigned char *)(&hp->inet_num))[0],
  1693. X                ((unsigned char *)(&hp->inet_num))[1],
  1694. X                ((unsigned char *)(&hp->inet_num))[2],
  1695. X                ((unsigned char *)(&hp->inet_num))[3],
  1696. X                hp->acc_cnt,
  1697. X                (hp->inhibit) ? '*' : ((hp->active) ? '+' : ' '),
  1698. X                ctime(&(hp->last_acc)));
  1699. X    }
  1700. X
  1701. X    fclose(fp);
  1702. X}
  1703. X
  1704. X/****************************************************************************
  1705. X* Client database initialization routine.  Reads in .ROGUE_HOSTS.
  1706. X****************************************************************************/
  1707. X
  1708. init_htab()        /* always have 2 entries -- 0, MAXINT */
  1709. X{
  1710. X    FILE *fp;
  1711. X    HTAB    *hp;
  1712. X    char  buf[1024];
  1713. X    unsigned int i1,i2,i3,i4;
  1714. X    unsigned long hnum;
  1715. X
  1716. X    if(!(htab = (HTAB *) malloc(sizeof(HTAB)*HALLOC_SIZE)))
  1717. X                { perror("grow_htab malloc"); exit(1); }
  1718. X    htab[0] = hzero;
  1719. X    htab[1] = hzero;
  1720. X    htab[1].inet_num = ~0;
  1721. X    hcnt = 2;
  1722. X    htot = HALLOC_SIZE;
  1723. X
  1724. X    if(fp = fopen(".ROGUE_HOSTS","r"))
  1725. X    {
  1726. X    while(fgets(buf,sizeof(buf),fp))
  1727. X    {
  1728. X        if(*buf < '0' || *buf > '9') continue;
  1729. X
  1730. X        sscanf(buf,"%d.%d.%d.%d",&i1,&i2,&i3,&i4);
  1731. X        ((unsigned char *) (&hnum))[0] = i1;
  1732. X        ((unsigned char *) (&hnum))[1] = i2;
  1733. X        ((unsigned char *) (&hnum))[2] = i3;
  1734. X        ((unsigned char *) (&hnum))[3] = i4;
  1735. X        hp = find_host(hnum);
  1736. X        hp->inhibit = 1;
  1737. X    }
  1738. X    fclose(fp);
  1739. X    }
  1740. X}
  1741. END_OF_FILE
  1742. if test 4133 -ne `wc -c <'server_host.c'`; then
  1743.     echo shar: \"'server_host.c'\" unpacked with wrong size!
  1744. fi
  1745. # end of 'server_host.c'
  1746. fi
  1747. if test -f 'server_lib.c' -a "${1}" != "-c" ; then 
  1748.   echo shar: Will not clobber existing file \"'server_lib.c'\"
  1749. else
  1750. echo shar: Extracting \"'server_lib.c'\" \(5990 characters\)
  1751. sed "s/^X//" >'server_lib.c' <<'END_OF_FILE'
  1752. X    /*********************************************************************\
  1753. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1754. X    *                                                                     *
  1755. X    *  You may copy or modify this file in any manner you wish, provided  *
  1756. X    *  that this notice is always included, and that you hold the author  *
  1757. X    *  harmless for any loss or damage resulting from the installation or *
  1758. X    *  use of this software.                                              *
  1759. X    \*********************************************************************/
  1760. X
  1761. X#include "server_def.h"
  1762. X
  1763. extern int errno;
  1764. X
  1765. static int myport = 0;
  1766. static int myfd;
  1767. static int interrupted = 0;
  1768. X
  1769. server_interrupt()
  1770. X{
  1771. X    interrupted = 1;
  1772. X    signal(SIGALRM,server_interrupt);
  1773. X}
  1774. X
  1775. X/****************************************************************************
  1776. X*  This is the message filter.  It is called by main with a timeout value.
  1777. X*  If timeout is -1, it will never time out.  Otherwise, it waits for a
  1778. X*  message.  If timed out, it returns.  Otherwise it pass it through checks.
  1779. X*  Those message that passed get sent to the dispatch loop.
  1780. X****************************************************************************/
  1781. X
  1782. server_loop(timeout)
  1783. X    unsigned long timeout;
  1784. X{
  1785. X    unsigned long cur_time;
  1786. X    HTAB *hp;
  1787. X    UBUF rbuf;
  1788. X    struct sockaddr_in from;
  1789. X    unsigned u, sum, mask;
  1790. X    int retval, bytes, old;
  1791. X    unsigned char *s, *d, *t;
  1792. X
  1793. X    while(1)
  1794. X    {
  1795. X    mask = 1 << myfd;
  1796. X    if(interrupted) { dump_htab(); interrupted = 0; }
  1797. X    retval = _x_select(&mask, timeout);
  1798. X
  1799. X    if(retval == -1) { if(errno = EINTR) continue;
  1800. X               perror("select"); exit(1); }
  1801. X
  1802. X    if(retval == 1)    /* an incoming message is waiting */
  1803. X    {
  1804. X        bytes = sizeof(from);
  1805. X        if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
  1806. X                    &from,&bytes)) < UBUF_HSIZE) continue;
  1807. X
  1808. X        rbuf.len = ntohs(rbuf.len);
  1809. X        if(rbuf.len+UBUF_HSIZE > bytes) continue;    /* truncated.  */
  1810. X
  1811. X        if(!(hp = find_host(from.sin_addr.s_addr)))
  1812. X            { fputs("find host failed\n",stderr); exit(0); }
  1813. X
  1814. X        if(hp->inhibit) continue;
  1815. X
  1816. X        old = 0;
  1817. X        cur_time = time((time_t *) 0);
  1818. X
  1819. X        if(hp->next_key != rbuf.key)
  1820. X        {
  1821. X        if(hp->last_key == rbuf.key)
  1822. X        {
  1823. X            if(hp->active && (cur_time < hp->last_acc + 3)) continue;
  1824. X            old = 1;
  1825. X
  1826. X        } else
  1827. X        if(hp->active && (cur_time < hp->last_acc + 60)) continue;
  1828. X        }
  1829. X
  1830. X        hp->active   =        1;
  1831. X        hp->last_acc = cur_time;
  1832. X
  1833. X        s = (unsigned char *) &rbuf;
  1834. X        d = s + bytes;
  1835. X        u = rbuf.sum; rbuf.sum = 0;
  1836. X        for(t = s, sum = bytes; t < d; sum += *t++);
  1837. X        sum = (sum + (sum >> 8)) & 0xff;
  1838. X        if(sum != u) continue;            /* wrong check sum */
  1839. X
  1840. X        rbuf.pos = ntohl(rbuf.pos);
  1841. X        server_get_packet(bytes,&rbuf,old,hp,&from);
  1842. X
  1843. X    } else return(0);                /* got a timeout */
  1844. X    }
  1845. X}
  1846. X
  1847. X/****************************************************************************
  1848. X* Routine to return a 16-bit key with random number in the first 8-bits and
  1849. X* zero in the second 8-bits.
  1850. X****************************************************************************/
  1851. X
  1852. get_next_key()
  1853. X{
  1854. X    unsigned long k;
  1855. X
  1856. X    k = random();
  1857. X    k = k ^ (k >> 8) ^ (k >> 16) ^ (k << 8);
  1858. X
  1859. X    return(k & 0xff00);
  1860. X}
  1861. X
  1862. X/****************************************************************************
  1863. X* Generic routine for sending reply back to clients.
  1864. X*        from: client address structure.
  1865. X*          ub: pointer to the message buffer.
  1866. X*  len1, len2: lengths of the two data regions in the message buffer.
  1867. X****************************************************************************/
  1868. X
  1869. server_reply(from,ub,len1,len2)
  1870. X    struct sockaddr_in *from;
  1871. X    UBUF *ub;
  1872. X    int   len1, len2;
  1873. X{
  1874. X    unsigned char *s, *t, *d;
  1875. X    unsigned sum;
  1876. X
  1877. X    if(dbug) fprintf(stderr,"snd (%c,%d,%d,%lu) ---> %d.%d.%d.%d\n",
  1878. X                ub->cmd, len1, len2, ub->pos,
  1879. X                ((unsigned char *)(&(from->sin_addr.s_addr)))[0],
  1880. X                ((unsigned char *)(&(from->sin_addr.s_addr)))[1],
  1881. X                ((unsigned char *)(&(from->sin_addr.s_addr)))[2],
  1882. X                ((unsigned char *)(&(from->sin_addr.s_addr)))[3]);
  1883. X
  1884. X    ub->len = htons(len1);
  1885. X    ub->pos = htonl(ub->pos);
  1886. X
  1887. X    ub->sum = 0;
  1888. X    s = (unsigned char *) ub;
  1889. X    d = s + (len1 + len2 + UBUF_HSIZE);
  1890. X    for(t = s, sum = 0; t < d; sum += *t++);
  1891. X    ub->sum = sum + (sum >> 8);
  1892. X
  1893. X    if(sendto(myfd,(char *)ub,(len1 + len2 + UBUF_HSIZE),0,
  1894. X            from,sizeof(struct sockaddr_in)) == -1)
  1895. X                        { perror("sendto"); exit(1); }
  1896. X}
  1897. X
  1898. X/****************************************************************************
  1899. X* Send an error string.
  1900. X****************************************************************************/
  1901. X
  1902. send_error(from,ub,msg)
  1903. X    struct sockaddr_in *from;
  1904. X    UBUF *ub;
  1905. X    char *msg;
  1906. X{
  1907. X    char *d;
  1908. X
  1909. X    for(d = ub->buf; *d++ = *msg++; );
  1910. X    ub->cmd = CC_ERR;
  1911. X
  1912. X    server_reply(from,ub,d-ub->buf,0);
  1913. X}
  1914. X
  1915. X/****************************************************************************
  1916. X* Send a block of data read from the file 'fp'.  Offset information is
  1917. X* contained in the input ub message buffer, which also doubles as the output
  1918. X* message buffer.
  1919. X****************************************************************************/
  1920. X
  1921. send_file(from,ub,fp)
  1922. X    struct sockaddr_in *from;
  1923. X    UBUF *ub;
  1924. X    FILE *fp;
  1925. X{
  1926. X    int bytes;
  1927. X
  1928. X    fseek(fp,ub->pos,0);
  1929. X    bytes = fread(ub->buf, 1, UBUF_SPACE, fp);
  1930. X    server_reply(from,ub,bytes,0);
  1931. X}
  1932. X
  1933. X/****************************************************************************
  1934. X* The tow UDP socket initialization routines.  One for running alone.
  1935. X* The other for running under inetd.
  1936. X****************************************************************************/
  1937. X
  1938. init_network(port)
  1939. X    int port;
  1940. X{
  1941. X    myport = port;
  1942. X
  1943. X    if((myfd = _x_udp(&myport)) == -1) { perror("socket open"); exit(1); }
  1944. X
  1945. X    if(dbug)
  1946. X    {
  1947. X    fprintf(stderr,"listening on port %d\n",myport);
  1948. X    fflush(stderr);
  1949. X    }
  1950. X
  1951. X    signal(SIGALRM,server_interrupt);
  1952. X}
  1953. X
  1954. init_inetd()
  1955. X{
  1956. X    myfd = dup(0);
  1957. X
  1958. X    signal(SIGALRM,server_interrupt);
  1959. X}
  1960. END_OF_FILE
  1961. if test 5990 -ne `wc -c <'server_lib.c'`; then
  1962.     echo shar: \"'server_lib.c'\" unpacked with wrong size!
  1963. fi
  1964. # end of 'server_lib.c'
  1965. fi
  1966. if test -f 'server_main.c' -a "${1}" != "-c" ; then 
  1967.   echo shar: Will not clobber existing file \"'server_main.c'\"
  1968. else
  1969. echo shar: Extracting \"'server_main.c'\" \(5561 characters\)
  1970. sed "s/^X//" >'server_main.c' <<'END_OF_FILE'
  1971. X    /*********************************************************************\
  1972. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  1973. X    *                                                                     *
  1974. X    *  You may copy or modify this file in any manner you wish, provided  *
  1975. X    *  that this notice is always included, and that you hold the author  *
  1976. X    *  harmless for any loss or damage resulting from the installation or *
  1977. X    *  use of this software.                                              *
  1978. X    \*********************************************************************/
  1979. X
  1980. X#include "server_def.h"
  1981. X
  1982. X#define ERR(S) { send_error(from,ub,S); return; }
  1983. X
  1984. int inetd_mode =            0;
  1985. int dbug       =            0;
  1986. int   udp_port = DEF_FSP_PORT;
  1987. char *home_dir = DEF_FSP_HOME;
  1988. char *run_uid  =            0;
  1989. X
  1990. X/****************************************************************************
  1991. X*  This is the dispatch loop for message that has been accepted.
  1992. X*    bytes: size of the message received.
  1993. X*       ub: pointer to the message buffer.
  1994. X*      old: true if this message contains old sequence number (retransmit).
  1995. X*       hp: pointer to the entry for the client host who sent this message.
  1996. X*     from: pointer to the socket address structure of the client host.
  1997. X****************************************************************************/
  1998. X
  1999. server_get_packet(bytes,ub,old,hp,from)
  2000. X    int   bytes,old;
  2001. X    UBUF *ub;
  2002. X    HTAB *hp;
  2003. X    struct sockaddr_in *from;
  2004. X{
  2005. X    unsigned long inet_num;
  2006. X    unsigned l1, l2;
  2007. X    char *s1, *s2, *pe;
  2008. X    FILE *fp;
  2009. X
  2010. X    l1 = ub->len;
  2011. X    l2 = bytes - l1 - UBUF_HSIZE;
  2012. X    s1 = ub->buf;
  2013. X    s2 = ub->buf + l1;
  2014. X
  2015. X    if(dbug) fprintf(stderr,"rcv (%c,%d,%d,%lu) <--- %d.%d.%d.%d\n",
  2016. X        ub->cmd, l1, l2, ub->pos,
  2017. X        ((unsigned char *)(&hp->inet_num))[0],
  2018. X        ((unsigned char *)(&hp->inet_num))[1],
  2019. X        ((unsigned char *)(&hp->inet_num))[2],
  2020. X        ((unsigned char *)(&hp->inet_num))[3]);
  2021. X
  2022. X    if(!old) { hp->last_key = hp->next_key;
  2023. X           hp->next_key = get_next_key() + ((hp->last_key+1) & 0x00ff); }
  2024. X
  2025. X    ub->key  = hp->next_key;
  2026. X    inet_num = hp->inet_num;
  2027. X
  2028. X    switch(ub->cmd)
  2029. X    {
  2030. X      case CC_VERSION : { ERR(VERSION_STR); }
  2031. X
  2032. X      case CC_BYE     : { if(!old) hp->active = 0;
  2033. X              server_reply(from,ub,0,0);
  2034. X              return; }
  2035. X            
  2036. X      case CC_GET_DIR : { if((pe = check_path(s1,l1)) ||
  2037. X                 (pe = server_get_dir(s1,&fp))) ERR(pe);
  2038. X              send_file(from,ub,fp);
  2039. X              fclose(fp);
  2040. X              return; }
  2041. X
  2042. X      case CC_GET_FILE: { if((pe = check_path(s1,l1)) ||
  2043. X                     (pe = server_get_file(s1,&fp))) ERR(pe);
  2044. X              send_file(from,ub,fp);
  2045. X              fclose(fp);
  2046. X              return; }
  2047. X
  2048. X      case CC_DEL_FILE: { if(!old)
  2049. X                if((pe = check_path(s1,l1)) ||
  2050. X                   (pe = server_del_file(s1,inet_num))) ERR(pe);
  2051. X              server_reply(from,ub,0,0);
  2052. X              return; }
  2053. X
  2054. X      case CC_DEL_DIR : { if(!old)
  2055. X                if((pe = check_path(s1,l1)) ||
  2056. X                   (pe = server_del_dir(s1,inet_num))) ERR(pe);
  2057. X              server_reply(from,ub,0,0);
  2058. X              return; }
  2059. X
  2060. X      case CC_UP_LOAD : { if(!old)
  2061. X                if(pe = server_up_load(s1,l1,ub->pos,inet_num))
  2062. X                                      ERR(pe);
  2063. X              server_reply(from,ub,0,0);
  2064. X              return; }
  2065. X
  2066. X      case CC_INSTALL : { if(!old)
  2067. X                if((pe = check_path(s1,l1)) ||
  2068. X                   (pe = server_install(s1,inet_num))) ERR(pe);
  2069. X              server_reply(from,ub,0,0);
  2070. X              return; }
  2071. X
  2072. X      case CC_MAKE_DIR: { if(!old)
  2073. X                if((pe = check_path(s1,l1)) ||
  2074. X                   (pe = server_make_dir(s1,inet_num))) ERR(pe);
  2075. X              if(pe = server_get_pro(s1,inet_num)) ERR(pe);
  2076. X              server_reply(from,ub,strlen(ub->buf)+1,0);
  2077. X              return; }
  2078. X
  2079. X      case CC_GET_PRO : { if((pe = check_path(s1,l1)) ||
  2080. X                 (pe = server_get_pro(s1,inet_num))) ERR(pe);
  2081. X              server_reply(from,ub,strlen(ub->buf)+1,0);
  2082. X              return; }
  2083. X
  2084. X      case CC_SET_PRO : { if(!old)
  2085. X                if((pe = check_path(s1,l1)) ||
  2086. X                   (pe = server_set_pro(s1,s2,inet_num))) ERR(pe);
  2087. X              if(pe = server_get_pro(s1,inet_num)) ERR(pe);
  2088. X              server_reply(from,ub,strlen(ub->buf)+1,0);
  2089. X              return; }
  2090. X    }
  2091. X}
  2092. X
  2093. arg_err()
  2094. X{
  2095. X    fputs("arg: -h absolute_path    set home directory.\n",stderr);
  2096. X    fputs("     -p udp_port_number  set port number.\n",stderr);
  2097. X    fputs("     -u uid_number       assume this uid after startup.\n",stderr);
  2098. X    fputs("     -d                  turn on debug mode.\n",stderr);
  2099. X    exit(1);
  2100. X}
  2101. X
  2102. main(argc,argv)
  2103. X    int argc;
  2104. X    char **argv;
  2105. X{
  2106. X    int t;
  2107. X
  2108. X    inetd_mode = !strcmp(argv[0],"in.fspd");
  2109. X
  2110. X    if(inetd_mode)
  2111. X    {
  2112. X    init_inetd();
  2113. X    freopen("/dev/null","r",stdin);
  2114. X    freopen("/dev/null","w",stdout);
  2115. X    freopen("/dev/null","w",stderr);
  2116. X    }
  2117. X
  2118. X    for(t = 1; t < argc; t++)
  2119. X    {
  2120. X    if(argv[t][0] == '-') switch(argv[t][1])
  2121. X    {
  2122. X        case 'd':    dbug++; break;
  2123. X
  2124. X        case 'h':    if(argv[t][2]) home_dir = argv[t]+2; else
  2125. X            if(argv[t+1] ) home_dir = argv[++t]; else
  2126. X                                arg_err();
  2127. X            break;
  2128. X
  2129. X        case 'u':    if(argv[t][2]) run_uid = argv[t]+2; else
  2130. X            if(argv[t+1] ) run_uid = argv[++t]; else
  2131. X                                arg_err();
  2132. X            break;
  2133. X
  2134. X        case 'p':    if(argv[t][2]) udp_port = atoi(argv[t]+2); else
  2135. X            if(argv[t+1] ) udp_port = atoi(argv[++t]); else
  2136. X                                arg_err();
  2137. X            break;
  2138. X
  2139. X        default : arg_err();
  2140. X
  2141. X    } else arg_err();
  2142. X    }
  2143. X
  2144. X    if(!inetd_mode)
  2145. X    {
  2146. X    init_network(udp_port);
  2147. X    if(!dbug) { freopen("/dev/null","r",stdin);
  2148. X            freopen("/dev/null","w",stdout);
  2149. X            freopen("/dev/null","w",stderr); }
  2150. X    }
  2151. X
  2152. X    if(run_uid) if(setuid(atoi(run_uid)) != 0) exit(1);
  2153. X    init_home_dir();
  2154. X    init_htab();
  2155. X
  2156. X    srandom(getpid());
  2157. X
  2158. X    if(inetd_mode) {          server_loop(120*1000L); }  /* 2 minutes */
  2159. X          else { while(1) server_loop(      -1L); }
  2160. X
  2161. X    exit(0);
  2162. X}
  2163. END_OF_FILE
  2164. if test 5561 -ne `wc -c <'server_main.c'`; then
  2165.     echo shar: \"'server_main.c'\" unpacked with wrong size!
  2166. fi
  2167. # end of 'server_main.c'
  2168. fi
  2169. if test -f 'udp_io.c' -a "${1}" != "-c" ; then 
  2170.   echo shar: Will not clobber existing file \"'udp_io.c'\"
  2171. else
  2172. echo shar: Extracting \"'udp_io.c'\" \(4013 characters\)
  2173. sed "s/^X//" >'udp_io.c' <<'END_OF_FILE'
  2174. X    /*********************************************************************\
  2175. X    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  2176. X    *                                                                     *
  2177. X    *  You may copy or modify this file in any manner you wish, provided  *
  2178. X    *  that this notice is always included, and that you hold the author  *
  2179. X    *  harmless for any loss or damage resulting from the installation or *
  2180. X    *  use of this software.                                              *
  2181. X    \*********************************************************************/
  2182. X
  2183. X#include "common_def.h"
  2184. X
  2185. static struct sockaddr_in INET_ZERO = { AF_INET };
  2186. X
  2187. extern int errno;
  2188. X#define DSIZE (sizeof(int)*8)
  2189. X#define SAVE(A) { int sav; sav = errno; A; errno = sav; }
  2190. X
  2191. X#ifndef EXOS_IPC
  2192. X
  2193. X#include <netdb.h>
  2194. X
  2195. extern long inet_addr();
  2196. X
  2197. X_x_udp(port)
  2198. X    int *port;
  2199. X{
  2200. X    int f, len, zz;
  2201. X    struct sockaddr_in me ;
  2202. X    struct sockaddr_in sin;
  2203. X
  2204. X    me = sin = INET_ZERO;
  2205. X
  2206. X    me.sin_port = htons((unsigned short) *port);
  2207. X    me.sin_family = AF_INET;
  2208. X    if((f=socket(AF_INET,SOCK_DGRAM,0)) == -1) return(-1);
  2209. X    if( setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(int)&zz,sizeof(zz)) < 0 ||
  2210. X        bind(f,(struct sockaddr *) &me,(len = sizeof(me))) < 0 ||
  2211. X        getsockname(f,(char *)&sin,&len) < 0)
  2212. X                                { SAVE(((void) close(f))); return(-1); }
  2213. X    if(!*port) *port = ntohs((unsigned short) sin.sin_port); return(f);
  2214. X}      
  2215. X
  2216. X_x_adr(host,port,his)
  2217. X    struct sockaddr_in *his;
  2218. X    char *host;
  2219. X    int port;
  2220. X{
  2221. X    char myhost[128];
  2222. X    struct hostent *H;
  2223. X    int    i;
  2224. X    char *s, *d;
  2225. X    *his = INET_ZERO;
  2226. X    if(!host) (void) gethostname(host = myhost,sizeof(myhost));
  2227. X    if((his->sin_addr.s_addr = inet_addr(host)) != -1)
  2228. X    {   his->sin_family = AF_INET;
  2229. X    } else
  2230. X    if(H = gethostbyname(host))
  2231. X    {   for(s = (char *)H->h_addr, d = (char *)&his->sin_addr, i = H->h_length;
  2232. X                        i--; *d++ = *s++);
  2233. X        his->sin_family = H->h_addrtype;
  2234. X    } else return(-1);
  2235. X    his->sin_port = htons((unsigned short) port);
  2236. X    return(0);
  2237. X}
  2238. X
  2239. X_x_select(rf, tt)       /* tt is in unit of ms */
  2240. X    int *rf;
  2241. X    long tt;
  2242. X{
  2243. X    struct timeval timeout;
  2244. X    if(tt != -1)
  2245. X    {
  2246. X        timeout.tv_sec  =  tt / 1000;
  2247. X        timeout.tv_usec = (tt % 1000)*1000;
  2248. X        return(select(DSIZE, rf, (int *) 0, (int *) 0, &timeout));
  2249. X    }
  2250. X       
  2251. X    return(select(DSIZE, rf, (int *) 0, (int *) 0, (struct timeval *) 0));
  2252. X}
  2253. X#endif  /* not EXOS_IPC */
  2254. X
  2255. X#ifdef EXOS_IPC
  2256. X
  2257. extern long rhost();
  2258. X
  2259. X_x_udp(port)
  2260. X    int *port;
  2261. X{
  2262. X    struct sockaddr_in sin; int f;
  2263. X
  2264. X    sin = INET_ZERO;
  2265. X    sin.sin_family = AF_INET;
  2266. X    sin.sin_port   = htons((unsigned short) *port);
  2267. X    if((f = socket(SOCK_DGRAM, (struct sockproto *) 0, &sin, SO_REUSEADDR))
  2268. X                            == -1) return(-1);
  2269. X    sin = INET_ZERO;
  2270. X    if(socketaddr(f,&sin) == -1) { SAVE(((void) close(f))); return(-1); }
  2271. X    if(!*port) *port = ntohs((unsigned short) sin.sin_port); return(f);
  2272. X}
  2273. X
  2274. X_x_adr(host,port,his)
  2275. X    char *host;
  2276. X    int port;
  2277. X    struct sockaddr_in *his;
  2278. X{
  2279. X    char myhost[128];
  2280. X    int f;
  2281. X
  2282. X    *his = INET_ZERO;
  2283. X    if(!host) (void) gethostname(host = myhost,sizeof(myhost));
  2284. X
  2285. X    his->sin_family = AF_INET;
  2286. X    his->sin_port   = htons((unsigned short) port);
  2287. X
  2288. X    if((his->sin_addr.s_addr = rhost(&host)) == -1) return(-1);
  2289. X
  2290. X    return(0);
  2291. X}
  2292. X
  2293. X_x_select(readfds, tt)
  2294. X    int *readfds;
  2295. X    long tt;                /* Time to wait in miniseconds. */
  2296. X{
  2297. X    int  code;
  2298. X    long mask = *readfds;
  2299. X
  2300. X    if(tt & 0xc0000000) tt = 0x3fffffff;/* It does not like 0x7fffffff. */
  2301. X
  2302. X    code = select(DSIZE, &mask, (long *) 0, tt);
  2303. X
  2304. X    *readfds = mask;
  2305. X
  2306. X    return(code);
  2307. X}
  2308. X
  2309. recvfrom(s, msg, len, flags, from, fromlen)
  2310. X    char *msg;
  2311. X    int s, len, flags, *fromlen;
  2312. X    struct sockaddr_in *from;
  2313. X{
  2314. X    return(receive(s,from,msg,len));
  2315. X}
  2316. X
  2317. sendto(s, msg, len, flags, to, tolen)
  2318. X    char *msg;
  2319. X    int s, len, flags, tolen;
  2320. X    struct sockaddr_in *to;
  2321. X{
  2322. X     to->sin_family = AF_INET;
  2323. X     return(send(s,to,msg,len));
  2324. X}
  2325. X
  2326. X#endif /* EXOS_IPC */
  2327. END_OF_FILE
  2328. if test 4013 -ne `wc -c <'udp_io.c'`; then
  2329.     echo shar: \"'udp_io.c'\" unpacked with wrong size!
  2330. fi
  2331. # end of 'udp_io.c'
  2332. fi
  2333. echo shar: End of archive 2 \(of 3\).
  2334. cp /dev/null ark2isdone
  2335. MISSING=""
  2336. for I in 1 2 3 ; do
  2337.     if test ! -f ark${I}isdone ; then
  2338.     MISSING="${MISSING} ${I}"
  2339.     fi
  2340. done
  2341. if test "${MISSING}" = "" ; then
  2342.     echo You have unpacked all 3 archives.
  2343.     rm -f ark[1-9]isdone
  2344. else
  2345.     echo You still need to unpack the following archives:
  2346.     echo "        " ${MISSING}
  2347. fi
  2348. ##  End of shell archive.
  2349. exit 0
  2350.